//
//  WBAPIManager.swift
//  Swift_Weibo
//
//  Created by Tim on 2019/8/26.
//  Copyright © 2019 Tim. All rights reserved.
//

import Foundation
import Moya
import Result
import RxSwift


/// API 公共 URL
var base_url : String {
    get {
        #if DEBUG
        return "https://api.weibo.com"
        #elseif RELEASE
        return "https://api.weibo.com"
        #endif
    }
}

/// 微博 app_id
let kAppKey       = "3967415363"

/// 微博 app_secret
let kAppSecret    = "ad2739358bbfb5a52490843778c2020a"

var kAccess_token : String {
    get {
        return "2.00J8V6mB4yrU1Eded243eaa8iCoV4D"
    }
    set {}
}

let uid : Int64 = 1631476007


let disposeBag    = DisposeBag()


enum WBAPIMnager {
    // 参数说明：
    // sinceId: 若指定此参数，则返回ID比since_id大的微博（即比since_id时间晚的微博），默认为0。
    // maxId  : 若指定此参数，则返回ID小于或等于max_id的微博，默认为0。
    case public_status(sinceId: Int64, maxId: Int64)
    
    /// 获取未读消息数
    case unread_count(uid: Int64)
}

extension WBAPIMnager : TargetType {
    
    var baseURL: URL {
        switch self {
        case .public_status:
            return URL(string: base_url)!
        case .unread_count:
            return URL(string: "https://rm.api.weibo.com")!
        }
        
    }
    
    var path: String {
        switch self {
        case .public_status:
            return "/2/statuses/home_timeline.json"
        case .unread_count:
            return "/2/remind/unread_count.json"
        }
    }
    
    var method: Moya.Method {
        switch self {
        case .public_status, .unread_count:
            return .get
        }
    }
    
    var sampleData: Data {
        return "".data(using: String.Encoding.utf8)!
    }
    
    var task: Task {
        switch self {
        case .public_status, .unread_count:
            return .requestParameters(parameters: parameters!, encoding: parameterEnconding)
        }
    }
    
    var headers: [String : String]? {
        return ["Content-type" : "application/json"]
    }
    
    var parameters : [String : Any]? {
        switch self {
        case .public_status(let sinceId, let maxId):
            return ["access_token" : kAccess_token, "since_id" : sinceId, "max_id" : maxId]
        case .unread_count(let uid):
            return ["access_token" : kAccess_token, "uid" : uid]
        }
    }
    
    var parameterEnconding : ParameterEncoding {
        switch self {
        case .public_status, .unread_count:
            return URLEncoding.default
        }
    }
}

// 创建自定义的 provider 实例，统一接口，用于发送网络请求
//let WBApiProvider = MoyaProvider(endpointClosure: endpointClosure, requestClosure: requestClosure, stubClosure: stubClosure, manager: MoyaProvider<WBAPIMnager>.defaultAlamofireManager(), plugins: [CustomPlugin()])
let WBApiProvider = MoyaProvider<WBAPIMnager>(plugins: [CustomPlugin()])


/// endpoints闭包
/// 它负责把您的enum值映射成一个Endpoint实例对象
fileprivate let endpointClosure = { (target: WBAPIMnager) -> Endpoint in
    let url = URL(target: target).absoluteString
    return Endpoint(url: url, sampleResponseClosure: {.networkResponse(200, target.sampleData)}, method: target.method, task: target.task, httpHeaderFields: target.headers)
}

/// 创建一个 requestClosure, 用于最后编辑网络请求
/// 逻辑说明：先获 Moya 默认使用 request 实例，定制 request 使用参数
/// 例如：修改请求超时时间
fileprivate let requestClosure = { (endpoint: Endpoint, done: MoyaProvider.RequestResultClosure) in
    do {
        // 取得默认的 request
        var request : URLRequest = try endpoint.urlRequest()
        request.timeoutInterval = 60.0                      // 请求超时时间修改
        done(.success(request))
    } catch {
        let moyaError = MoyaError.underlying(error, nil)
        done(.failure(moyaError))
    }
}

/// 单元测试模块闭包
/// stub是一个测试相关的概念, 通过stub你可以返回一些假数据
/// Moya的stub原理很简单，如果Provider决定Stub，那么就返回Endpoint中的假数据；否则就进行实际的网络请求。
/// 提供的三种模式:
/// .never -> 不stub,
/// .immediate -> 立即返回数据, 使用本参数将会不进行网络请求，直接返回 success
/// .delayedStub(seconds) -> 根据传参决定延迟多久返回数据（单位：秒） 主要用于模拟网络请求延时 使用本参数将会不进行网络请求，直接返回 success
fileprivate let stubClosure = { (target: WBAPIMnager) -> Moya.StubBehavior in
    return .never
}

